package br.com.infnet.cultbook.repository.dao.common.impl;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import br.com.infnet.cultbook.repository.dao.common.BaseDAO;

@Stateless
public class BaseDAOImpl<T> implements BaseDAO<T> {

	@PersistenceContext(unitName = "banco")
	protected EntityManager manager;

	public BaseDAOImpl() {
		this.manager = manager;
	}
	
	@Override
	public void persist(T unsaved) {
		unsaved = manager.merge(unsaved);
		manager.persist(unsaved);
	}
	
	@Override
	public <T> T persistAndReturn(T unsaved) {
		unsaved = manager.merge(unsaved);
		manager.persist(unsaved);
		return unsaved;
	}
	
	@Override
	public void remove(T saved) {
		saved = manager.merge(saved);
		manager.remove(saved);
	}

	@Override
	public <T> T findById(Long id) {
		Query query = manager.createQuery("select value from "
				+ ((Class) ((ParameterizedType) this.getClass()
						.getGenericSuperclass()).getActualTypeArguments()[0])
						.getSimpleName() + " value where value.id = :value");
		query.setParameter("value", id);
		
		try{
			return (T) query.getSingleResult();
		}catch(NoResultException nore){
			return null;
		}
	}

	@Override
	public List<T> list() {
		Query query = manager.createQuery("from "
				+ ((Class) ((ParameterizedType) this.getClass()
						.getGenericSuperclass()).getActualTypeArguments()[0])
						.getSimpleName());
		return query.getResultList();
	}
	
	@Override
	public List<T> list(int page, int size) {
		Query query = manager.createQuery("from " + 
		((Class)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getSimpleName());
		query.setMaxResults(size);
		query.setFirstResult(page);
		return query.getResultList();
	}
	
	@Override
	public List<T> listLastEntries(int size) {
		Query query = manager.createQuery("from " + 
		((Class)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getSimpleName() + " order by id desc");
		query.setMaxResults(size);
		return query.getResultList();
	}

	@Override
	public int countAll() {
		Query query = manager.createQuery("select count(*) from " +
		((Class)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]).getSimpleName());
		
		Long count = (Long)query.getSingleResult();
		
		return count.intValue();
	}

}
